import java.util.Objects;
import java.util.Random;

public class Main {

    static Random r = new Random();

    public static int solve(Point head) {
        // Alg description:
        // Two Pointers, one move twice speed of another. If they meet, loop is detected.
        // To find the start of the loop, reset slow pointer to head. Both move same speed, meeting at the loop start.
        Point slow=head,fast=head;
        do {
            if (Objects.isNull(fast.next)) break;
            if (Objects.isNull((fast.next).next)) break;
            slow = slow.next;
            fast = (fast.next).next;
        } while (!slow.equals(fast));

        if (Objects.isNull(fast.next) || Objects.isNull((fast.next).next)) {
            return -1;
        }

        slow = head;
        while (!slow.equals(fast)) {
            slow = slow.next;
            fast = fast.next;
        }
        return slow.value;
    }

    public static void testGiven(Problem problem) {
        if (problem.answer==-2) return;

        int ans = solve(problem.head);
        if (ans == problem.answer) {
            System.out.println("Passed. ans: " + problem.answer);
        } else {
            System.out.println("Failed. expecting: " + ans + " answering: " + ans);
        }
    }
    public static void testRecursive(int n) {
        for (int i = 0; i < n; i++) {
            final Problem problem = new Problem();
            testGiven(problem);
        }
    }

    public static void main(String[] args) {

        final Problem problemNoLoop = new Problem(10);
        testGiven(problemNoLoop);

        final Problem problem = new Problem(1,0);
        testGiven(problem);

        testRecursive(8);
    }
}